package gormsqlite

import (
	"os"
	"path/filepath"
	"strings"

	Log "github.com/cihub/seelog"
	"gopkg.in/ini.v1"

	//"gorm.io/driver/sqlite"//这个驱动需要使用CGO
	"github.com/glebarez/sqlite" //这个驱动不需要使用CGO
	gg "gorm.io/gorm"
	"gorm.io/gorm/logger"
)

type GormDB = *gg.DB

var (
	globGormDB *gg.DB //主数据库操作对象
)

// 初始化
func init() {
	//SetupLogger()

	root := ""
	exePath, err := os.Executable()
	if err != nil {
		root = "."
	}

	root, _ = filepath.EvalSymlinks(filepath.Dir(exePath))

	// configFilePath := strings.Replace(root+"/config/app.ini", "\\", "/", -1)
	configFilePath := filepath.Join(root, "config", "app.ini")

	// _, err = os.Stat(configFilePath) //os.Stat获取文件信息
	// if err != nil {
	// 	if !os.IsExist(err) {
	// 		Log.Error("配置文件不存在:", err)
	// 		os.Exit(1)
	// 		return
	// 	}
	// }
	if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
		Log.Error("配置文件不存在:", configFilePath)
		os.Exit(1)
	}

	cfg, err := ini.Load(configFilePath)
	if err != nil {
		Log.Error("配置文件读取错误:", err)
		os.Exit(1)
	}

	if !cfg.HasSection("DataSource") {
		Log.Debug("配置文件没有DataSource,不进行数据库连接")
		return
	}

	DataSource := cfg.Section("DataSource")

	globGormDB, err = NewDb(DataSource)
	if err != nil {
		Log.Error("连接数据库错误:", err)
		return
	}
}

func NewDb(DataSource *ini.Section) (*gg.DB, error) {
	dbName := "mysql" //如果是sqlite则是数据库文件路径和名称
	value, _ := DataSource.GetKey("MainDb")
	if value != nil {
		dbName = value.String()
	}

	PrintSql := false
	value, _ = DataSource.GetKey("PrintSql")
	if value != nil {
		tmp, _ := value.Int()
		PrintSql = tmp == 1
	}

	AutoMigrate := false //是否开启AutoMigrate功能(会创建表、缺失的外键、约束、列和索引)
	value, _ = DataSource.GetKey("AutoMigrate")
	if value != nil {
		tmp, _ := value.Int()
		AutoMigrate = tmp == 1
	}

	dbConfig := &gg.Config{
		DisableForeignKeyConstraintWhenMigrating: !AutoMigrate,
	}

	if PrintSql {
		dbConfig.Logger = logger.Default.LogMode(logger.Info) //开启sql打印
	}

	if strings.HasPrefix(dbName, "./") {
		root := ""
		exePath, err := os.Executable()
		if err != nil {
			root = "."
		}

		root, _ = filepath.EvalSymlinks(filepath.Dir(exePath))

		// dbName = strings.Replace(dbName, "./", root+"/", 1)
		// dbName = strings.Replace(dbName, "\\", "/", -1)
		// dbName = strings.Replace(dbName, "//", "/", -1)
		dbName = filepath.Join(root, strings.TrimPrefix(dbName, "./"))
	}

	createFileDir(dbName)
	return gg.Open(sqlite.Open(dbName), dbConfig)
}

// 取gorm操作对象
func GetDB() GormDB {
	return globGormDB
}

/**
 * 创建文件所在文件夹
 * 注意:必须是文件,否则只能创建出上级路径
 * @param filePath 文件路径
 * @return bool:是否成功(如果路径已经存在则不会创建,但返回true); error:错误信息
 */
func createFileDir(filePath string) (bool, error) {
	path := filepath.Dir(filePath) //获取上级目录
	_, err := os.Stat(path)        //os.Stat获取文件信息
	if err == nil {                //获取成功,说明文件存在
		return true, nil
	}

	if os.IsExist(err) { //再次判断路径是否存在,也可以使用os.IsNotExist(err)来判断是否不存在
		return true, nil
	}

	err = os.MkdirAll(path, os.ModePerm)
	if err != nil {
		return false, err
	}

	return true, nil
}
